<html>
<head><meta charset="utf-8"><title>Custom inner attribute output · t-compiler/help · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/index.html">t-compiler/help</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html">Custom inner attribute output</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="246280550"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246280550" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jerry Liu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246280550">(Jul 16 2021 at 21:12)</a>:</h4>
<p>Hi guys, I have been developing a custom inner attribute as procedural-macro. The problem I found is that the input tokens seem to be wrapped into a <code>pub mod</code> without identifier and will throw an error if I parse it with <code>syn</code>. Is there any workaround on this or an easy way to obtain the tokens of entire crate instead of inner attribute?</p>



<a name="246281943"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246281943" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246281943">(Jul 16 2021 at 21:22)</a>:</h4>
<p><span class="user-mention" data-user-id="410549">@Jerry Liu</span> I can take a look at how much work it would be to fix that. What's your use-case for obtaining the tokens of the whole crate?</p>



<a name="246282351"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246282351" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jerry Liu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246282351">(Jul 16 2021 at 21:26)</a>:</h4>
<p>Thanks! I am developing an attribute to generate a macro that expands to some part of my source code:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#![attribute_name]</span><span class="w"></span>
<span class="c1">//src code for crate</span>
</code></pre></div>
<p>It should generate a macro:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[macro_export]</span><span class="w"></span>
<span class="fm">macro_rules!</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="p">()</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">//some source code that I extract by visiting}</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>The src that needs to be in the macro are labeled with other attributes</p>



<a name="246282943"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246282943" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jerry Liu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246282943">(Jul 16 2021 at 21:32)</a>:</h4>
<p>Maybe this can makes it more clear:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#![allow(unused_variables)]</span><span class="w"></span>
<span class="cp">#![allow(dead_code)]</span><span class="w"></span>
<span class="cp">#![allow(unused_must_use)]</span><span class="w"></span>

<span class="cp">#![prusti_contracts::export_all]</span><span class="w"></span>
<span class="k">extern</span><span class="w"> </span><span class="k">crate</span><span class="w"> </span><span class="n">prusti_contracts</span><span class="p">;</span><span class="w"></span>
<span class="k">use</span><span class="w"> </span><span class="n">prusti_contracts</span>::<span class="o">*</span><span class="p">;</span><span class="w"></span>

<span class="cp">#[extern_spec]</span><span class="w"></span>
<span class="k">mod</span> <span class="nn">std</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">mod</span> <span class="nn">mem</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">use</span><span class="w"> </span><span class="n">prusti_contracts</span>::<span class="o">*</span><span class="p">;</span><span class="w"></span>

<span class="w">        </span><span class="cp">#[ensures(*a == old(*b) &amp;&amp; *b == old(*a))]</span><span class="w"></span>
<span class="w">        </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">swap</span><span class="p">(</span><span class="n">a</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="kt">i32</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="c1">// pub fn swap&lt;T: std::cmp::PartialEq + Copy&gt;(a: &amp;mut T, b: &amp;mut T);</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="p">;</span><span class="w"></span>

<span class="w">    </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">swap</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">y</span><span class="p">);</span><span class="w"></span>

<span class="w">    </span><span class="fm">assert!</span><span class="p">(</span><span class="mi">42</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="fm">assert!</span><span class="p">(</span><span class="mi">5</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">y</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>The <code>export_all</code> is the attribute I am working on. I am hoping to generate a macro to expands to </p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[extern_spec]</span><span class="w"></span>
<span class="k">mod</span> <span class="nn">std</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">mod</span> <span class="nn">mem</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">use</span><span class="w"> </span><span class="n">prusti_contracts</span>::<span class="o">*</span><span class="p">;</span><span class="w"></span>

<span class="w">        </span><span class="cp">#[ensures(*a == old(*b) &amp;&amp; *b == old(*a))]</span><span class="w"></span>
<span class="w">        </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">swap</span><span class="p">(</span><span class="n">a</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="kt">i32</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="c1">// pub fn swap&lt;T: std::cmp::PartialEq + Copy&gt;(a: &amp;mut T, b: &amp;mut T);</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>So that I can reuse these codes in another crate</p>



<a name="246283683"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246283683" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246283683">(Jul 16 2021 at 21:39)</a>:</h4>
<p>One unresolved question is the behavior of crate-level inner attributes with regard to out-of-line modules (e.g. <code>mod foo;</code>)</p>



<a name="246283803"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246283803" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246283803">(Jul 16 2021 at 21:40)</a>:</h4>
<p>proc-macro attributes on out-of-line modules (e.g. <code>#[my_attr mod foo;</code>) are unstable, because it's undecided whether or not they should see the literal <code>mod foo;</code> tokens, or the contents of the module loaded from disk</p>



<a name="246283820"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246283820" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246283820">(Jul 16 2021 at 21:40)</a>:</h4>
<p>crate-level attributes have the same problem, since <code>mod foo;</code> statements are part of the crate</p>



<a name="246283913"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246283913" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246283913">(Jul 16 2021 at 21:41)</a>:</h4>
<p><span class="user-mention" data-user-id="410549">@Jerry Liu</span> That kind of literal code reuse (copying the whole <code>#[extern_mod]</code> mod std) seems kind of unusual. You could run into problems if you're using any other macros within that nested module</p>



<a name="246283927"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246283927" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246283927">(Jul 16 2021 at 21:42)</a>:</h4>
<p>since they might not be imported in the other crate</p>



<a name="246283978"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246283978" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246283978">(Jul 16 2021 at 21:42)</a>:</h4>
<p>Do you have full control over all of the crates involved?</p>



<a name="246284908"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246284908" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jerry Liu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246284908">(Jul 16 2021 at 21:51)</a>:</h4>
<p><span class="user-mention silent" data-user-id="125294">Aaron Hill</span> <a href="#narrow/stream/182449-t-compiler.2Fhelp/topic/Custom.20inner.20attribute.20output/near/246283978">said</a>:</p>
<blockquote>
<p>Do you have full control over all of the crates involved?</p>
</blockquote>
<p>Yes I do have full control here since <code>#[extern_spec]</code> simply just another attribute in the project.</p>
<p><span class="user-mention silent" data-user-id="125294">Aaron Hill</span> <a href="#narrow/stream/182449-t-compiler.2Fhelp/topic/Custom.20inner.20attribute.20output/near/246283913">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="410549">Jerry Liu</span> That kind of literal code reuse (copying the whole <code>#[extern_mod]</code> mod std) seems kind of unusual. You could run into problems if you're using any other macros within that nested module</p>
</blockquote>
<p>I don't think we will be using any macros inside the nested module (if you don't count <code>#[extern_spec]</code>). The literal code reuse is the strategy now because the project is basically a plugin for <code>rustc</code> and we are trying to preserve some code to reuse across crate</p>



<a name="246286359"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246286359" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Vadim Petrochenkov <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246286359">(Jul 16 2021 at 22:07)</a>:</h4>
<p>We should perhaps emit an immediate error on attempt to use a macro attribute at crate level.<br>
They are not supported, was never supported, and I'm not sure it's a good idea to support them in the future.</p>



<a name="246286949"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246286949" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jerry Liu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246286949">(Jul 16 2021 at 22:14)</a>:</h4>
<p>So what would be a good way to obtain tokenstream of the entire crate and process with <code>syn</code>?</p>



<a name="246293293"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Custom%20inner%20attribute%20output/near/246293293" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jerry Liu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Custom.20inner.20attribute.20output.html#246293293">(Jul 17 2021 at 00:02)</a>:</h4>
<p>Do anyone know what will actually be the valid output for an <code>inner_attribute</code>? Since it's wrapped in a mod without identifier clearly it won't be a valid output. What should I return in the attribute?</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>